<template>
  <view class="bx-form" style="">
    <view class="form-name bg-white padding-sm text-blue" v-if="formName&&allField.length > 0" @click="showForm">
      <text>{{formName||''}}</text>
      <text class="cuIcon-right icon" style="color: #bbb;" :class="{'to-bottom':show}"> </text>
    </view>
    <view class="" v-show="show"  v-if="allField.length > 0">
      <view v-for="(item, index) in allField" :key="index">
        <view class="section-name" v-if="item.section&&item.display">
          <view class="section">
            {{item.section}}
          </view>
        </view>
        <formItem :procData="procData" :field="item" :pageFormType="BxformType" :showTextarea="showTextarea"
          :fieldsModel="fieldModel" :service="service" :detailFiledData="detailFiledData" ref="fitem"
          @on-form-item="onItemButtons($event)" @on-value-change="onValChange($event)"
          @on-value-blur="onValBlur($event)" @get-cascader-val="getCascaderVal" @picker-change="pickerchange"
          @show-option-list="showOptionlist"></formItem>
      </view>
    </view>
    <slot></slot>
  </view>
</template>

<script>
  import formItem from '@/components/bx-form/bx-form-item.vue';
  import evaluatorTo from '@/common/evaluator.js';
  export default {
    name: 'bx-form',
    components: {
      formItem
    },
    props: {
      formName: {
        type: String
      },
      fields: {
        type: Array,
        default () {
          return [];
        }
      },
      procData: {
        type: Object,
        default () {
          return {};
        }
      },
      defaultCondition: {
        type: Array,
        default () {
          return [];
        }
      },
      pageType: {
        type: String,
        default () {
          return '';
        }
      },
      BxformType: {
        type: String,
        default () {
          return 'form';
        }
      },
      service: {
        type: String,
        default () {
          return '';
        }
      },
      showTextarea: {
        type: Boolean,
        default: true
      },
      moreConfig: {
        type: Object,
        default () {
          return {};
        }
      },
      detailFiledData: {
        type: Object,
        default () {
          return {};
        }
      },
      defaultValue: {
        type: Object,
      }
    },
    computed: {
      setFields() {
        return this.fields.slice(0, 5)
      }
    },
    data() {
      return {
        allField: this.fields,
        fieldModel: {},
        fieldData: {},
        oldField: [],
        oldFieldModel: {},
        specialCol: [],
        more_config: {},
        show: true
      };
    },
    created() {
      if (this.fieldModel.length > 0) {
        this.fieldModel = this.fieldModel.map(item => {
          if (!item.value && item.defaultValue) {
            item.value = item.defaultValue;
          }
          return item;
        });
        this.oldField = this.deepClone(this.fields);
        this.oldField.forEach((item, index) => {
          this.oldFieldModel[item.column] = item.value;
        });
      }
      this.getAllField();
    },
    methods: {
      showForm() {
        this.show = !this.show
      },
      pickerchange(oriData) {
        console.log('oriData------', oriData, this.allField);
        let filed = this.allField;
        console.log(this.allField);
      },
      setRelationColumnValue(allField, colArr, col_relation) {
        const self = this;
        let more_config = self.more_config;
        let returnValue = null;
        switch (col_relation.value.type) {
          case 'calc': //计算
            (() => {
              let valueArr = col_relation.value.value.value.map(relationitem => {
                if (relationitem.type === 'col') {
                  const finalArr = colArr.filter(col => col.column === relationitem.val);
                  if (finalArr.length > 0) {
                    return finalArr[0].value;
                  }
                } else if (relationitem.type === 'value') {
                  return Number(relationitem.val);
                }
              });
              switch (col_relation.value.value.type) {
                case 'add': //加
                  valueArr.forEach(item => {
                    returnValue += Number(item);
                  });
                  break;
                case 'sub': //减
                  (() => {
                    let result = 0;
                    if (Array.isArray(valueArr) && valueArr.length > 0) {
                      valueArr.forEach((item, index) => {
                        if (index !== 0) {
                          result += item;
                        }
                      });
                      returnValue = valueArr[0] - result;
                    }
                  })();
                  // returnValue = valueArr[0] - valueArr[1];
                  break;
                case 'multi': //乘
                  returnValue = 1;
                  valueArr.forEach(item => {
                    returnValue *= Number(item);
                  });
                  break;
                case 'divide': //除
                  returnValue = valueArr[0] / valueArr[1];
                  break;
              }
            })();
            break;
          case 'col': //字段对应值
            (() => {
              this.allField.forEach(col => {
                if (col.column === col_relation.value.value) {
                  returnValue = col.value;
                }
              });
            })();
            break;
        }
        this.allField.forEach((field, index) => {
          if (col_relation.dest_col === field.column) {
            field.value = returnValue;
            this.$set(this.allField, index, field);
          }
        });
      },
      setShowExp() {},
      async setCallbackColumnValue(serviceCall, condition) {
        let url = this.getServiceUrl(serviceCall.app, serviceCall.service, 'select');
        let req = {
          serviceName: serviceCall.service,
          colNames: ['*'],
          condition: condition
        };
        const res = await this.$http.post(url, req);
        if (res.data.state === 'SUCCESS') {
          console.log('setCallbackColumnValue,', res.data.data);
          if (res.data.data.length > 0) {
            const resData = res.data.data[0];
            const colArr = Object.keys(resData);
            this.allField.forEach((field, index) => {
              colArr.forEach(item => {
                if (item === field.column) {
                  field.value = resData[item];
                  this.$set(this.allField, index, field);
                }
              });
            });
          }
        }
        return;
        let returnValue = '';
        switch (serviceCall.value.type) {
          case 'value':
            returnValue = serviceCall.value.value;
            break;
          case 'calc':
            (() => {
              let valueArr = serviceCall.value.value.value.map(serviceCallitem => {
                if (serviceCallitem.type === 'col') {
                  const finalArr = this.allField.filter(col => col.column === serviceCallitem.val);
                  if (finalArr.length > 0) {
                    return finalArr[0].value;
                  }
                } else if (serviceCallitem.type === 'value') {
                  return serviceCallitem.val;
                }
              });
              switch (serviceCall.value.value.type) {
                case 'add': //加
                  valueArr.forEach(item => {
                    returnValue += Number(item);
                  });
                  break;
                case 'sub': //减
                  returnValue = valueArr[0] - valueArr[1];
                  break;
                case 'multi': //乘
                  returnValue = 1;
                  valueArr.forEach(item => {
                    returnValue *= Number(item);
                  });
                  break;
                case 'divide': //除
                  returnValue = valueArr[0] / valueArr[1];
                  break;
              }
            })();
            break;
          case 'col':
            (() => {
              this.allField.forEach(col => {
                if (col.column === serviceCall.value.value) {
                  returnValue = col.value;
                }
              });
            })();
            break;
        }
        this.allField.forEach((item, index) => {
          if (item.column === serviceCall.dest_col) {
            item.value = returnValue;
            this.$set(this.allField, index, item);
          }
        });
      },
      onItemButtons(e) {
        this.$emit('on-form-item', e);
        return e;
      },
      getAllField() {
        let self = this;
        if (this.fields.length > 0) {
          let fields = this.fields;
          this.oldField.forEach((item, index) => {
            this.oldFieldModel[item.column] = item.value;
          });
          this.allField = []
          fields.forEach((itemData, index) => {
            this.fieldModel[itemData.column] = itemData.value;
            let item = this.fieldModel;
            if (itemData.hasOwnProperty('option_list_v2')) {
              if (itemData.option_list_v2 &&
                typeof itemData.option_list_v2.srv_app_exp === 'object' &&
                itemData.option_list_v2.srv_app_exp.type === 'column' &&
                itemData.option_list_v2.srv_app_exp.value &&
                item[itemData.option_list_v2.srv_app_exp.value]
              ) {
                itemData.option_list_v2.srv_app = item[itemData.option_list_v2.srv_app_exp.value];
              }
              if (itemData?.option_list_v2?.conditions) {
                let conditions = itemData.option_list_v2.conditions;
                conditions = conditions.map(cond => {
                  if (cond.value_exp && cond.value_exp.type === 'column' && cond.value_exp.value) {
                    if (item[cond.value_exp.value]) {
                      cond.value = item[cond.value_exp.value];
                    }
                  }
                  return item;
                });
              }
            }
            if (itemData.hasOwnProperty('isShowExp') && item.hasOwnProperty(itemData.column)) {
              itemData['showExp'] = this.evalInTo(itemData, item);
              itemData['display'] =
                itemData.isShowExp && itemData.isShowExp.length > 0 ? this.colItemShowExps(itemData, item) &&
                itemData.display : itemData.display === false ? false : true;
            } else {
              itemData['showExp'] = itemData['showExp'] || true;
            }
            if (itemData.formulaShow) {
              itemData['showExp'] = evaluatorTo(item, itemData.formulaShow);
              itemData['display'] = itemData['showExp'];
            }
            itemData.valid = {
              column: itemData.column,
              valid: true,
              msg: '不能为空!'
            };
            // #ifdef H5
            if (itemData?.x_if) {
              let row = this.fieldModel;
              let ret = eval("(" + itemData.x_if + ")(row);");
              itemData.display = ret && ret;
            }
            // #endif

            this.allField.push(itemData)
            // return itemData;
          })
          // this.allField = fields.map((itemData, index) => {
          //   this.fieldModel[itemData.column] = itemData.value;
          //   let item = this.fieldModel;
          //   if (itemData.hasOwnProperty('option_list_v2')) {
          //     if (itemData.option_list_v2 &&
          //       typeof itemData.option_list_v2.srv_app_exp === 'object' &&
          //       itemData.option_list_v2.srv_app_exp.type === 'column' &&
          //       itemData.option_list_v2.srv_app_exp.value &&
          //       item[itemData.option_list_v2.srv_app_exp.value]
          //     ) {
          //       itemData.option_list_v2.srv_app = item[itemData.option_list_v2.srv_app_exp.value];
          //     }
          //     if (itemData?.option_list_v2?.conditions) {
          //       let conditions = itemData.option_list_v2.conditions;
          //       conditions = conditions.map(cond => {
          //         if (cond.value_exp && cond.value_exp.type === 'column' && cond.value_exp.value) {
          //           if (item[cond.value_exp.value]) {
          //             cond.value = item[cond.value_exp.value];
          //           }
          //         }
          //         return item;
          //       });
          //     }
          //   }
          //   if (itemData.hasOwnProperty('isShowExp') && item.hasOwnProperty(itemData.column)) {
          //     itemData['showExp'] = this.evalInTo(itemData, item);
          //     itemData['display'] =
          //       itemData.isShowExp && itemData.isShowExp.length > 0 ? this.colItemShowExps(itemData, item) &&
          //       itemData.display : itemData.display === false ? false : true;
          //   } else {
          //     itemData['showExp'] = itemData['showExp'] || true;
          //   }
          //   if (itemData.formulaShow) {
          //     itemData['showExp'] = evaluatorTo(item, itemData.formulaShow);
          //     itemData['display'] = itemData['showExp'];
          //   }
          //   itemData.valid = {
          //     column: itemData.column,
          //     valid: true,
          //     msg: '不能为空!'
          //   };
          //   this.specialCol.forEach(special => {
          //     if (special.column === itemData.column) {
          //       special.value ? (this.fieldModel[itemData.column] = special.value) : '';
          //       special.value ? (itemData['value'] = special.value) : '';
          //       special.disabled ? (itemData['disabled'] = special.disabled) : '';
          //       special.display ? (itemData['display'] = special.display) : '';
          //     }
          //   });
          //   return itemData;
          // }).map(itemData => {
          //   // #ifdef H5
          //   if (itemData?.x_if) {
          //     let row = this.fieldModel;
          //     let ret = eval("(" + itemData.x_if + ")(row);");
          //     itemData.display = ret && ret;
          //   }
          //   return itemData
          //   // #endif
          // })
          if (typeof this.fieldModel === 'object' && Object.keys(this.fieldModel).length > 0) {
            if (typeof this.defaultValue === 'object' && Object.keys(this.defaultValue).length > 0) {
              Object.keys(this.defaultValue).forEach(key => {
                if (!this.fieldModel[key]) {
                  this.fieldModel[key] = this.defaultValue[key]
                }
              })
            }
          }
        }
      },
      onValChange(e) {
        const self = this;
        if (e.type === 'number') {
          this.fieldModel[e.column] = Number(e.value);
        } else {
          this.fieldModel[e.column] = e.value;
        }
        e.value = this.fieldModel[e.column];
        const fieldModel = this.deepClone(this.fieldModel);
        this.allField = this.allField.map((item, index) => {
          item.display = item.isShowExp && item.isShowExp.length > 0 ? this.colItemShowExps(item, this.fieldModel) :
            item.display === false ? false : true;
          if (item.column === e.column) {
            item.value = e.value;
          }
          return item;
        });
        this.allField.forEach(fileIf => {
          if (fileIf.formulaShow) {
            let isIfShow = evaluatorTo(fieldModel, fileIf.formulaShow);
            fileIf.display = isIfShow;
          }
        });

        if (e.bx_col_type === 'fk' && e.colData && typeof e.colData === 'object' && Array.isArray(e.colData) !== true &&
          Object.keys(e.colData).length > 0) {
          //冗余
          this.allField.forEach(item => {
            if (item.redundant && typeof item.redundant === 'object' && item.redundant.dependField === e.column) {
              if (item.redundant.trigger === 'always') {
                item.value = e.colData[item.redundant.refedCol];
              } else if (item.redundant.trigger === 'isnull') {
                if (!item.value) {
                  item.value = e.colData[item.redundant.refedCol];
                }
              }
              this.fieldModel[item.column] = item.value;
            }
          });
        }
        console.log('valueChange', e, this.fieldModel[e.column], this.fieldModel);
        this.$emit('value-blur', e, this.fieldModel);
      },
      onValBlur(e) {
        console.log('e', e, this.fieldModel, this.fieldModel[e.column]);
        this.fieldModel[e.column] = e.value;
        this.$emit('value-blur', e, this.fieldModel);
      },
      getDetailfieldModel() {
        return this.fieldModel;
      },
      getFieldModel() {
        console.log(this.fieldModel, 'getFieldModel');
        let valid = 0;
        let showsNum = 0;
        this.allField.map((item, index) => {
          let valids = this.$refs.fitem[index].getValid();
          console.log('字段校验', valids, item);
          if (item.display) {
            showsNum++;
            if (valids.valid) {
              valid++;
            }
          }
        });
        console.log(valid, showsNum);
        if (valid === showsNum) {
          console.log('表单校验通过', showsNum, valid, this.fieldModel);
          let model = {};
          switch (this.pageType) {
            case 'update':
              for (let key in this.fieldModel) {
                if (this.oldFieldModel[key] !== this.fieldModel[key]) {
                  model[key] = this.fieldModel[key];
                }
              }
              break;
            case 'add':
              for (let key in this.fieldModel) {
                if (this.fieldModel[key] === '' && key !== 'openid') {
                  delete this.fieldModel[key];
                }
              }
              model = this.fieldModel;
              break;
            default:
              model = this.fieldModel;
              break;
          }
          console.log('this.fieldModel', this.fieldModel, model);
          if (Object.keys(model).length > 0) {
            return model;
          } else {
            uni.showToast({
              title: '没有需要提交的数据',
              icon: 'none'
            });
            return false;
          }
        } else {
          console.log('表单校验失败', showsNum, valid, this.fieldModel);
          uni.showToast({
            title: '请填写完信息后，再尝试提交',
            icon: 'none'
          });
          return false;
        }
      },
      getCascaderVal(val) {
        if (val) {
          this.$emit('get-cascader-val', val);
        } else {
          this.$emit('get-cascader-val');
        }
      },
      showOptionlist(e) {
        this.$emit('show-option-list', e);
      },
      onReset() {
        this.allField = this.deepClone(this.oldField);
        console.log(this.oldField, 'this.oldField');
        try {
          return true;
        } catch (e) {
          return false;
          //TODO handle the exception
        }
      }
    },
    watch: {
      fields: {
        handler: function(newval, old) {
          this.getAllField();
        },
        deep: true
      },
      moreConfig: {
        handler: function(newval, old) {
          if (newval) {
            this.more_config = this.deepClone(newval);
          }
        },
        deep: true
      },
      fieldModel: {
        deep: true,
        handler(newVal, oldVal) {}
      }
    }
  };
</script>

<style lang="scss" scoped>
  .bx-form {}

  .form-name {

    display: flex;
    justify-content: space-between;
    align-items: center;

    .icon {
      transition: transform .3s ease;

      &.to-bottom {
        transform: rotate(90deg);
      }
    }

  }

  .section-name {
    color: #0081ff;
    padding: 10rpx 30rpx 0;
    font-weight: bold;
    margin-top: 2px;
    display: flex;
    justify-content: flex-start;
    background-color: #fff;

    // border-radius: 10px 10px 0 0 ;
    .section {
      position: relative;
      display: flex;
      align-items: center;
      // &::before {
      //   display: inline-block;
      //   // position: absolute;
      //   content: '';
      //   // bottom: -5px;
      //   height: 1px;
      //   width:50px;
      //   background-color: #0081ff;
      //   // left:45%;
      //   border-radius: 5px;
      //   left: calc(-75%);
      //   top: 50%;
      //   margin-right: 10px;

      // }

      // &::after {
      //   display: inline-block;
      //   // position: absolute;
      //   content: '';
      //   // bottom: -5px;
      //   height: 1px;
      //   top: 50%;
      //   width: 50px;
      //   background-color: #0081ff;
      //   // left:45%;
      //   border-radius: 5px;
      //   right: calc(-75%);;
      //   margin-left: 10px;
      // }
    }

  }
</style>
